<template>
	<view class="page-arena-detail">
		<scroll-view class="scroll-content"  scroll-x enable-flex>
			<view class="book-date-list">
				<MxDateBtn v-for="date in dateList" :dayObj="date" :active.sync="activeDay" />
			</view>
			
		</scroll-view>
		<view class="arena-detail-list" v-if="pauseAappointment">
			<view class="list-head">
				<view>时间</view>
				<view v-for="part in arenaInfo.parts">{{part.name}}</view>
			</view>
			<view class="list-info">
				<view class="list-time">
					<view class="list-time-item" v-for="item in getArenaListByPart(arenaInfo.parts[0].name)">{{item.fragment}}</view>
				</view>

				<view class="list-arena" v-for="part in arenaInfo.parts">
					<MxBookTimeBtn class="cmp-book-time-btn" v-for="(time, index) in getArenaListByPart(part.name)" :section="time" :name="arenaInfo.name" :part="part.name" :continuity="part.continuity" :year="activeDay.year" :month="activeDay.month" :date="activeDay.date" :index="index" @select="onSelect" />
				</view>
			</view>
		</view>
		<view v-if="!pauseAappointment" style="color: red;text-align: center;">超过当天{{booktime}}点暂停预约</view>
		<!-- 裁判列表 -->
		<!-- <MxRefereeList v-if="haveReferee" :list="refereeList" @select="onSelectReferee" @deselect="onDeselectReferee" :selected="selectedRefereeIdx" :booked="bookedReferees" /> -->
		<MxBuyButton v-if="arenaInfo.parts && pauseAappointment" class="cmp-buy-button" :total="total" title="立即预约" @buy="onBook" />
	</view>
</template>

<script>
	/**
	 * 连续限制以半场为单位，设置了连续选择限制后，不能取消单个，点击取消是取消半场内所有已选择的 (因为如果设置了连续选择限制后，仍然可以单个取消，那么就变成可以选择单个了，那这个限制的意义就不大了)
	 * 最少限制和最多限制是以整场来计, 所有半场加在一起
	 * 目前切换日期后会清除已选择，需要重新选择。因为没有像指弹头篮球小程序那样底部显示已选择的场次，不过其实指弹头篮球切换日期后虽然保留了上一个日期已选择的场次，但是在新日期里点击选择就会清除上一个日期的所有选择
	 */
	import MxBookTimeBtn from '@/components/book-arena/MxBookTimeBtn.vue'
	import MxRefereeList from '@/components/book-arena/MxRefereeList.vue'
	import MxDateBtn from '@/components/book-arena/MxDateBtn.vue'
	import arenaMixin from '@/common/mixins/arena.js'
	import MxBuyButton from '@/components/common/MxBuyButton.vue';
	import { createNamespacedHelpers, mapActions } from 'vuex'
	const { mapState, mapMutations, mapGetters } = createNamespacedHelpers('arena')
	import dayjs from 'dayjs'
	import * as arenaApi from '@/api/arena.js'
	import * as refereeApi from '@/api/referee.js'
	  import { wxPayment } from '@/utils/app'

	export default {
		mixins: [arenaMixin],
		components: {
			MxBookTimeBtn,
			MxDateBtn,
			MxBuyButton,
			MxRefereeList
		},
		data() {
			return {
				booktime: 0,
				// 场地id
				arenaId: 0,
				
				arenaMinimum: 2, // 最少需要预约 n 场，默认为 1
				arenaMaximum: 5, // 最多只能预约 n 场，默认为 0 不限制
				arenaList: [
					{
						name: '一号场',
						part: '南半场',
						continuity: 2, // continuity: 是否限制必须连续选择 n 场，0 为不限制
						year: 2021,
						month: 6,
						date: 22,
						list: [
							{
								time: '8:00-8:30',
								status: 0, // status: 0 空闲，1 已预约
								price: 100
							},
							{
								time: '8:30-9:00',
								status: 0,
								price: 100
							},
							{
								time: '9:00-9:30',
								status: 1,
								price: 100
							},
							{
								time: '9:30-10:00',
								status: 0,
								price: 100
							},
							{
								time: '10:00-10:30',
								status: 0,
								price: 100
							},
							{
								time: '10:30-11:00',
								status: 0,
								price: 100
							},
							{
								time: '11:00-11:30',
								status: 0,
								price: 100
							},
							{
								time: '11:30-12:00',
								status: 0,
								price: 100
							},
							{
								time: '14:00-14:30',
								status: 0,
								price: 100
							}
						]
					},
					{
						name: '一号场',
						part: '北半场',
						continuity: 4,
						year: 2021,
						month: 6,
						date: 22,
						list: [
							{
							
								time: '8:00-8:30',
								status: 0,
								price: 100
							},
							{
								time: '8:30-9:00',
								status: 1,
								price: 100
							},
							{
								time: '9:00-9:30',
								status: 1,
								price: 100
							},
							{
								time: '9:30-10:00',
								status: 1,
								price: 100
							},
							{
								time: '10:00-10:30',
								status: 0,
								price: 100
							},
							{
								time: '10:30-11:00',
								status: 0,
								price: 100
							},
							{
								time: '11:00-11:30',
								status: 0,
								price: 100
							},
							{
								time: '11:30-12:00',
								status: 0,
								price: 100
							},
							{
								time: '14:00-14:30',
								status: 0,
								price: 100
							}
						]
					}
				],
				arenaInfo: {
					parts: [{
						name: ''
					}]
				},
				// 所有裁判列表
				refereeList: [],
				// 选择的裁判总价
				refereePrice: 0,
				// 已选择的裁判index
				selectedRefereeIdx: [],
				// 已选择的裁判id集合
				selectedRefereeIDs: [],
				pauseAappointment: true
			};
		},
		
		computed: {
			...mapState(['selectedArean', 'bookedReferees']),
			...mapGetters(['findSelectedAreanByIdx', 'bookedRefereesArr']),
			// 通过半场名字获取该半场对应时间场次信息
			getArenaListByPart() {
				return (name) => this.arenaInfo.parts.find(part => part.name == name).sessions
			},
			
			// 计算总价
			total() {
				let bookingPrice = this.selectedArean.reduce((total, arena) => (Number(total)*100 + Number(arena.section.price)*100)/100, 0)
				return (Number(this.refereePrice) * 100 + bookingPrice * 100) / 100
			},
			
			haveReferee() {
				return this.refereeList.length !== 0
			}
		},
		
		watch: {
			'bookedRefereesArr': function(val) {
				for(let list of val) {
					list.forEach(referee => {
						// 禁选裁判是否存在于已选择的裁判里，存在则删掉
						let index = this.selectedRefereeIDs.findIndex(selectedId => selectedId == referee.referee_id)
						if(index !== -1) {
							// 找到该裁判在所有裁判列表里的索引，将他从已选择的裁判索引数组里移除
							let refereeIndex = this.refereeList.findIndex(sele => sele.referee_id == referee.referee_id)
							let idx = this.selectedRefereeIdx.findIndex(selectedIndex => selectedIndex == refereeIndex)
							this.selectedRefereeIdx.splice(idx, 1)
							this.selectedRefereeIDs.splice(index, 1)
							const price = this.refereeList[refereeIndex].price
							this.refereePrice = (Number(this.refereePrice)*100 - Number(price)*100 ) / 100
						}
					})
				}
			}
		},

		onLoad(option) {
			// 同步场地列表页选择的日期
			// this.activeDay = dayjs(Number(option.date))
			
			this.activeDay = {
				year: option.year,
				month: option.month,
				date: option.date,
				day: option.day
			}
			this.arenaId = option.id
			this.booktime = option.booktime
			// 获取所有裁判
			// this.getAllReferee()
			
		
		},
		
		methods: {
			...mapActions(['checkInfo']),
			...mapMutations(['selectArena', 'deleteArena', 'addArenaContinuously', 'clearSelectedArena', 'addBookedReferees', 'removeBookedReferees', 'clearBookedReferees']),
			// 获取所有裁判列表
			getAllReferee() {
				refereeApi.all().then(res => {
					this.refereeList = res.data
				})
			},

			// 选择裁判时触发
			onSelectReferee(info) {
				this.selectedRefereeIdx.push(info.index)
				this.selectedRefereeIDs.push(info.refereeId)
				this.refereePrice = (Number(this.refereePrice)*100 + Number(info.price)*100) / 100
			},
			
			// 取消选择裁判时触发
			onDeselectReferee(info) {
				const idx = this.selectedRefereeIdx.findIndex(refereeIdx => info.index == refereeIdx)
				this.selectedRefereeIdx.splice(idx, 1)
				
				const id = this.selectedRefereeIDs.findIndex(refereeId => info.refereeId == refereeId)
				this.selectedRefereeIDs.splice(id, 1)
				
				this.refereePrice = (Number(this.refereePrice)*100 - Number(info.price)*100) / 100
			},
			
			// 用户切换日期时触发
			getList(year, month, date) {
				console.log(dayjs().$D)
				console.log(dayjs().$H)
				console.log(date)
				console.log(this.booktime)
				//超过当天10点暂停预约
				if(dayjs().$D != date && dayjs().$H >= this.booktime){
					this.pauseAappointment = false
				}
				
				// 清除裁判选择
				this.selectedRefereeIdx = []
				this.selectedRefereeIDs = []
				this.refereePrice = 0
				// 清空禁选裁判列表
				this.clearBookedReferees()
				
				arenaApi.parts({
					year,
					month,
					date,
					arena_id: this.arenaId
				}).then(res => {
					console.log(res)
					this.arenaInfo = res.data
					// 动态设置标题
					uni.setNavigationBarTitle({
						title: res.data.name
					})
				})
			},
			
			// 查询指定日期和时段下是否有裁判已被预订
			hasRefereeBooked(info){
				const date = `${info.year}-${info.month}-${info.date}`
				const timeFragment = info.section.fragment
				
				refereeApi.refereeInfo({date, timeFragment}).then(res =>  {
					console.log(res)
					const referees = res.data
					this.addBookedReferees({arena: info, referees})
				})
			},
			
			onSelect(info) {
				console.log(info)
				
				// 选择的该时段是否空闲
				if(info.section.status === 0) {
					const index = this.selectedArean.findIndex(arena => info.name == arena.name && info.part == arena.part && info.section.fragment == arena.section.fragment)
					// 若该时段已存在已选择时段列表中
					if(index !== -1) {
						this.deleteArena(index)
						return
					}
					
					// 检查最多预约场次限制
					if(this.arenaInfo.maximum && (this.selectedArean.length >= this.arenaInfo.maximum)) {
						uni.showToast({
							title: `最多预约${this.arenaInfo.maximum}场`,
							icon: 'none'
						})
						return
					}
					
					// 若选择的该半场有连续限制
					if(info.continuity > 1) {
						const timeList = this.getArenaListByPart(info.part)
						const index = info.index
						const continuity = info.continuity
						let selected = this.selectContinuously(index, continuity, timeList, info)
						if(!selected) {
							uni.showToast({
								title: `至少连续选择${continuity}场`,
								icon: 'none'
							})
						}else{
							// 将要添加的场次数量
							let arenaWillAdd = continuity
							// 判断当前选择是否在连选的头或尾添加，如果是则只添加这一个
							const infoHead = this.findSelectedAreanByIdx(info.index+1, info.part)
							const infoFoot = this.findSelectedAreanByIdx(info.index-1, info.part)
							if(infoHead !== -1 || infoFoot !== -1) {
								arenaWillAdd = 1
								selected = [info]
							}
							
							// 当存在可以连续选择 n 场时，先判断已选择的数量和连续选择数量的和是否大于最大选择限制
							if(this.arenaInfo.maximum && this.selectedArean.length + arenaWillAdd > this.arenaInfo.maximum) {
								const maximumText = this.arenaInfo.maximum !== 0 ? `,全场最多预约${this.arenaInfo.maximum}场`: ''
								uni.showToast({
									title: `${info.part}必须连续预约${continuity}场` + maximumText,
									icon: 'none'
								})
								return
							}
							
							// 逐一添加到已选择场次列表中
							selected.forEach(arena => {
								this.addArenaContinuously(arena)
								// 查询该时段是否有裁判已被预订
								this.hasRefereeBooked(arena)
							})
						}
						return
					}
					
					// 添加时段
					this.selectArena(info)
					// 查询该时段是否有裁判已被预订
					this.hasRefereeBooked(info)
				}
			},
			
			// 能否连续选择
			selectContinuously(index, continuity, timeList, info) {
				const clockwise = this.selectClockwise(index, continuity, timeList, info)
				if(clockwise) {
					return clockwise
				}
				
				const anticlockwise = this.selectAnticlockwise(index, continuity, timeList, info)
				if(anticlockwise) {
					return anticlockwise
				}
				
				const clockwiseAndAnti = this.selectClockwiseAndAntic(index, continuity, timeList, info)
				if(clockwiseAndAnti) {
					return clockwiseAndAnti
				}
				
				return false
				
			},
			
			// 顺时方向选择
			selectClockwise(index, continuity, timeList, info) {
				const arr = []
				// 判断顺时方向是否存在可以连续选择的 n 项
				for(let i=index, len=index+continuity; i<len; i++) {
					if(timeList[i]) {
						if(timeList[i].status !== 0) {
							return false
						}
					}else{
						return false
					}
					
					// 如果顺时方向中存在 n 个时段，且都为空闲状态
					arr.push(Object.assign({}, info, {
						index: i,
						section: timeList[i]
					}))
				}
				
				return arr
			},
			
			// 逆时方向选择
			selectAnticlockwise(index, continuity, timeList, info) {
				const arr = []
				// 判断逆时方向
				for(let i=index, len=index-continuity; i>len; i--) {
					if(timeList[i]) {
						if(timeList[i].status !== 0) {
							return false
						}
					}else{
						return false
					}
					
					// 如果逆时方向中存在 n 个时段，且都为空闲状态
					arr.push(Object.assign({}, info, {
						index: i,
						section: timeList[i]
					}))
				}
				
				return arr
			},
			
			// 同时判断顺时方向和逆时方向，两个方向加起来是否有 n 个时段可选择（连续的时段）
			selectClockwiseAndAntic(index, continuity, timeList, info) {
				const arr = []
				// 判断顺时方向存在多少可以连续选择的时段
				for(let i=index, len=index+continuity; i<len; i++) {
					if(timeList[i]) {
						if(timeList[i].status !== 0) {
							break
						}
					}else{
						break
					}
					
					// 如果顺时方向中存在该时段，且为空闲状态
					arr.push(Object.assign({}, info, {
						index: i,
						section: timeList[i]
					}))
				}
				
				// 判断逆时方向，顺时方向已判断当前点击的那个时段，故 index - 1
				for(let j=index-1, len=index-continuity; j>len; j--) {
					if(timeList[j]) {
						if(timeList[j].status !== 0) {
							break
						}
					}else{
						break
					}
					
					// 若当前数组长度已大于等于连续选择限制数量，则不再添加进数组
					if(arr.length >= continuity) {
						break
					}
					
					// 如果逆时方向中存在该时段，且为空闲状态
					arr.push(Object.assign({}, info, {
						index: j,
						section: timeList[j]
					}))
				}
				
				// 如果顺时方向和逆时方向可选择的连续时段加起来大于等于连续选择限制数量，则返回该数组
				if(arr.length >= continuity) {
					return arr
				}
				
				return false
			},
		
			// 立即预约
			onBook() {
				if(this.selectedArean.length < 1) {
					uni.showToast({
						title: `请选择您要预约的场次`,
						icon: 'none'
					})
					return
				}
				
				// 检查时段是否已过期
				console.log(this.selectedArean)
				let cannotBook = false
				this.selectedArean.forEach(book => {
					const theDay = dayjs().year(book.year).month(book.month - 1).date(book.date)
					
					const [ startTime, endTime ] = book.section.fragment.split('-')
					const startTimeArr = startTime.split(':')
					const endTimeArr = endTime.split(':')
					const theDayWithStartTime = theDay.hour(startTimeArr[0]).minute(startTimeArr[1])
					const theDayWithEndTime = theDay.hour(endTimeArr[0]).minute(endTimeArr[1])
					
					if(theDayWithEndTime.isBefore(dayjs())) {
						cannotBook = true
					}
				})
				
				if(cannotBook) {
					uni.showToast({
						title: `您选择的场次里包含已过去的时段，请注意选择~`,
						icon: 'none'
					})
					return
				}
				
				// 检查最少场次选择限制
				if(this.arenaInfo.minimum && this.selectedArean.length < this.arenaInfo.minimum) {
					uni.showToast({
						title: `至少预约${this.arenaInfo.minimum}场`,
						icon: 'none'
					})
					return
				}
				const params = {part_time_fragment_ids: []}
				this.selectedArean.forEach(item => {
					params.year = item.year
					params.month = item.month
					params.date = item.date
					params.part_time_fragment_ids.push(item.section.part_time_fragment_id)
				})
				params.refereeIds = this.selectedRefereeIDs
				params.part_time_fragment_ids = params.part_time_fragment_ids.join(',')
				console.log(params)
				// 订场之前检查用户是否已设置姓名和手机号
				this.checkInfo().then(res => {
					arenaApi.book(params).then(res => {
						console.log(res)
						wxPayment(res.data)
						  .then(() => this.$success('预订成功'))
						  .catch(err => this.$error('订单未支付'))
						  .finally(() => {
						    setTimeout(() => {
						    	// 清空已选择
						    	this.clearSelectedArena()
								// 清除裁判选择
								this.selectedRefereeIdx = []
								this.selectedRefereeIDs = []
								this.refereePrice = 0
								// 清空禁选裁判列表
								this.clearBookedReferees()
						    	// 重新获取当日场次信息
						    	this.getList(this.activeDay.year, this.activeDay.month, this.activeDay.date)
						    }, 1000)
						    
						  })
					})
				}).catch(err => {
					// setTimeout(() => {
					// 	uni.navigateTo({
					// 		url: "/pages/mine/user-info"
					// 	})
					// }, 1500)
				})
				
			}
		}
	}
</script>

<style scoped lang="scss">
	@import '@/common/scss/var.scss';
	
	page{
		padding-bottom: 50rpx;
	}

	.page-arena-detail {
		font-family: $font-family;
	.scroll-content{
		height: 200rpx;
	}
		.book-date-list {
			display: flex;
			white-space: nowrap;
			box-sizing: border-box;
			margin-top: 30rpx;
			/deep/.uni-scroll-view::-webkit-scrollbar {
				display: none
			}
		}

		.arena-detail-list {
			margin-bottom: 60rpx;
			.list-head {
				margin-top: 56rpx;
				box-shadow: 0 -1px 3px 0 rgba($color: #000000, $alpha: .16);
				width: 100%;
				min-height: 82rpx;
				border-top-left-radius: 8px;
				border-top-right-radius: 8px;
				display: flex;
				justify-content: center;

				&>view {
					flex: 1;
					display: flex;
					justify-content: center;
					align-items: center;
					color: $color-border;
					font-size: 16px;
					font-weight: bold;
				}
			}

			.list-info {
				display: flex;

				.list-time {
					flex: 1;
					display: flex;
					flex-direction: column;
					align-item: center;
					text-align: center;

					&>.list-time-item {
						height: 52rpx;
						margin-top: 36rpx;
						display: flex;
						justify-content: center;
						align-item: center;
						color: $color-border;
						font-size: 16px;
						font-weight: bold;
					}
				}

				.list-arena {
					flex: 1;
					display: flex;
					flex-direction: column;
					align-items: center;

					&>.cmp-book-time-btn {
						display: inline-flex;
						margin-top: 36rpx;
					}
				}
			}
		}
		.cmp-buy-button{
			margin-top: 100rpx;
			position: relative;
			left: 58rpx;
			transform: translateX(-50%);
		}
	}
</style>
